package pacman;
import java.io.IOException;

import communication.Communicator;

import maze.Location;
import maze.Maze;
import simulation.Simulator;

public abstract class Robot {
	private Location location; //The location the robot thinks he is (but not necessarily is)	
	private int rotation; //The rotation the robot thinks he has (but not necessarily has)
	private Maze maze; //The maze as the robot sees it (can be incomplete and/or inaccurate)
	
	private Communicator communicator;
	private Simulator simulator;
	
	public Location getLocation() {
		return location;
	}

	protected void setLocation(Location location) {
		this.location = location;
	}
	
	public void setSimulator(Simulator simulator) {
		this.simulator = simulator;
	}
	
	public Simulator getSimulator(){
		return simulator;
	}
	
	public void travel(int distance){
		
		if(communicator != null)
		{
			communicator.travel(distance);
		}
		
		//TODO: ONLY WORKS FOR GHOSTS, NOT FOR PACMAN!!!
		//simulator verplaatsing simuleren
		try {
			simulator.SimulateTravel((Ghost) this, distance);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//lokale locatie updaten (de robot denkt de volledige distance echt afgelegd te hebben, ongeacht er een muur in de weg staat of niet)
		double rotRad = Math.toRadians(getRotation());
		double newX = location.getX() + Math.cos(rotRad) * distance;
		double newY = location.getY() + Math.sin(rotRad) * distance;
		this.setLocation(new Location(newX, newY));		
	}

	/**
	 * Rotation is measured to the positive x axis.  So a positive rotation is counterclockwise
	 * @param degrees
	 */
	public void rotate(int degrees){
		if(communicator != null)
		{
			communicator.rotateRobot(degrees);
		}
		
		//TODO: ONLY WORKS FOR GHOSTS, NOT FOR PACMAN!!!
		//simulator verplaatsing simuleren
		simulator.SimulateRotation((Ghost) this, degrees);
		
		
		//lokale rotatie updaten
		setRotation((getRotation()+degrees)%360);
		
	}
	
	public int getRotation() {
		return rotation;
	}
		
	protected void setRotation(int rotation) {
		this.rotation = rotation;
	}

	public Maze getMaze() {
		return maze;
	}

	protected void setMaze(Maze maze) {
		this.maze = maze;
	}

	protected void setCommunicator(Communicator comm)
	{
		communicator = comm;
	}
	
	public Communicator getCommunicator()
	{
		return communicator;
	}
}
